using Devil;
using LitJson;
using System.Collections.Generic;

namespace GameToolkit.ContentProvider
{

    public interface InstanceWithTableData<T> where T : TableBase, new()
    {
        T TableData { get; }
    }

    public class TableBase //: IIdentified
    {
        public interface IOnSubmitTable
        {
            void OnSubmit(ITable table);
            void OnDispose(ITable table);
        }

        public static int CalculateSerializationID(ICollection<string> properties)
        {
            if (properties == null || properties.Count == 0)
                return 0;
            MinHeap<int> ids = new MinHeap<int>(properties.Count, (a, b) => a < b ? -1 : (a > b ? 1 : 0));
            foreach (var str in properties)
            {
                ids.Add(ParallelUtils.ToHash(str));
            }
            var id = 0;
            while (ids.Count > 0)
            {
                id = MathExt.Hash(id, ids.RemoveTop());
            }
            return id;
        }

        //private int _id;
        public int DataId { get; private set; }

#if UNITY_EDITOR
        string mFormatString;
#endif
        public virtual int SerializationID { get { return 0; } }

        public TableBase()
        {
        }

        public TableBase(int id)
        {
            DataId = id;
        }

        public void Init(JsonData jobj)
        {
#if UNITY_EDITOR
            if (jobj == null)
            {
                RTLog.LogError(LogCat.Table, string.Format("{0}.Init(JsonData) must has an instance of JsonData parameter", GetType()));
                return;
            }
            mFormatString = string.Format("<{0}>{1}", GetType().Name, jobj.ToJson());
#endif
            DataId = (int)jobj["id"];
            OnDeserialize(jobj);
            //OnInitialized();
        }

        protected virtual void OnDeserialize(JsonData data) { }

        //protected virtual void OnInitialized() { }

#if UNITY_EDITOR
        public override string ToString()
        {
            if (string.IsNullOrEmpty(mFormatString))
                mFormatString = string.Format("<{0}>", GetType().Name);
            return mFormatString;
        }
#endif

        //public virtual void ReadBinary(System.IO.BinaryReader reader)
        //{
        //    DataId = reader.ReadInt32();
        //}

        //public virtual void WriteBinary(System.IO.BinaryWriter writer)
        //{
        //    writer.Write(DataId);
        //}
    }

}